package com.hunliji.monitor.web.facade.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.hunliji.common.exception.WarnException;
import com.hunliji.monitor.manager.api.FeiShuManager;
import com.hunliji.monitor.manager.api.model.dto.FeishuUserInfoDTO;
import com.hunliji.monitor.service.api.AlertChatBindService;
import com.hunliji.monitor.service.api.AlertConfigService;
import com.hunliji.monitor.service.api.AlertUserBindService;
import com.hunliji.monitor.service.api.ChatGroupService;
import com.hunliji.monitor.service.api.UserInfoService;
import com.hunliji.monitor.service.api.model.bo.AlertChatBindBO;
import com.hunliji.monitor.service.api.model.bo.AlertConfigBO;
import com.hunliji.monitor.service.api.model.bo.AlertUserBindBO;
import com.hunliji.monitor.service.api.model.bo.ChatGroupBO;
import com.hunliji.monitor.service.api.model.bo.UserInfoBO;
import com.hunliji.monitor.service.api.model.param.QueryChatGroupParam;
import com.hunliji.monitor.share.component.convertor.ConverterFacade;
import com.hunliji.monitor.share.constants.AlertConstant;
import com.hunliji.monitor.share.enums.AtTypeEnum;
import com.hunliji.monitor.share.enums.MsgTypeEnum;
import com.hunliji.monitor.share.enums.ReceiveIdTypeEnum;
import com.hunliji.monitor.web.facade.AlertConfigFacade;
import com.hunliji.monitor.web.facade.FeiShuFacade;
import com.hunliji.monitor.web.model.param.AlertChatBindParam;
import com.hunliji.monitor.web.model.param.AlertConfigSaveParam;
import com.hunliji.monitor.web.model.param.AlertUserBindParam;
import com.hunliji.monitor.web.model.param.GetAlertChatBindQueryParam;
import com.hunliji.monitor.web.model.param.GetAlertUserBindQueryParam;
import com.hunliji.monitor.web.model.param.GetAllAlertConfigsParam;
import com.hunliji.monitor.web.model.param.GetUserConfigQueryParam;
import com.hunliji.monitor.web.model.param.QueryChatGroupQueryParam;
import com.hunliji.monitor.web.model.param.SaveUserConfigParam;
import com.hunliji.monitor.web.model.vo.AlertChatBindVO;
import com.hunliji.monitor.web.model.vo.AlertConfigVO;
import com.hunliji.monitor.web.model.vo.AlertUserBindVO;
import com.hunliji.monitor.web.model.vo.ChatGroupVO;
import com.hunliji.monitor.web.model.vo.UserInfoVO;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * File：AlertConfigFacadeImpl.java<br> Title: <br> Description: <br>
 *
 * @author lejin Date: 2022/10/10
 */
@Service
@Slf4j
public class AlertConfigFacadeImpl implements AlertConfigFacade {

    @Resource
    AlertConfigService alertConfigService;

    @Resource
    AlertChatBindService alertChatBindService;

    @Resource
    AlertUserBindService alertUserBindService;

    @Resource
    UserInfoService userInfoService;

    @Resource
    FeiShuManager feiShuManager;

    @Resource
    FeiShuFacade feiShuFacade;

    @Resource
    ChatGroupService chatGroupService;

    @Resource
    ConverterFacade converterFacade;

    @Override
    public List<AlertConfigVO> queryAlertConfigs(GetAllAlertConfigsParam getAllAlertConfigsParam) {
        AlertConfigBO alertConfigBO = converterFacade.convert(getAllAlertConfigsParam,
            AlertConfigBO.class);
        List<AlertConfigBO> alertConfigBOS = alertConfigService.listByQuery(alertConfigBO);
        return converterFacade.convertList(alertConfigBOS, AlertConfigVO.class);
    }

    @Override
    public List<UserInfoVO> queryUserInfoList(GetUserConfigQueryParam param){
        List<UserInfoBO> userInfoBOList = userInfoService.getListByQuery(param.getName(),
            param.getId());
        return converterFacade.convertList(userInfoBOList, UserInfoVO.class);
    }

    @Override
    public List<AlertUserBindVO> queryAlertUserBinds(
        GetAlertUserBindQueryParam getAlertUserBindQueryParam) {
        List<AlertUserBindBO> alertUserBindBOS = alertUserBindService.listByQuery(
            getAlertUserBindQueryParam.getAlertConfigId(),
            getAlertUserBindQueryParam.getUserInfoId());
        return converterFacade.convertList(alertUserBindBOS, AlertUserBindVO.class);
    }

    @Override
    public List<AlertChatBindVO> queryAlertChatBinds(
        GetAlertChatBindQueryParam getAlertChatBindQueryParam) {
        List<AlertChatBindBO> alertChatBindBOS = alertChatBindService.listByQuery(
            getAlertChatBindQueryParam.getAlertConfigId(),
            getAlertChatBindQueryParam.getChatGroupId());
        return alertChatBindBOS.stream().map(x -> {
            AlertChatBindVO alertChatBindVO = converterFacade.convert(x, AlertChatBindVO.class);
            if(StringUtils.isNotBlank(x.getAtUserInfoIds())){
                alertChatBindVO.setAtUserInfoId(
                    Lists.newArrayList(x.getAtUserInfoIds().split("\\|")));
            }
            return alertChatBindVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ChatGroupVO> queryChatGroups(QueryChatGroupQueryParam queryChatGroupQueryParam) {
        List<ChatGroupBO> chatGroupBOS = chatGroupService.query(
            converterFacade.convert(queryChatGroupQueryParam,
                QueryChatGroupParam.class));
        return converterFacade.convertList(chatGroupBOS, ChatGroupVO.class);
    }

    @Override
    public void saveAlertConfig(AlertConfigSaveParam param) {
        if(Objects.isNull(param.getId()) && (StringUtils.isBlank(param.getAlertId()) || StringUtils.isBlank(param.getProject()))){
            throw new WarnException("「告警配置id」或者「告警id+project」不能为空");
        }
        AlertConfigBO alertConfigBO = null;
        if(Objects.nonNull(param.getId())){
            alertConfigBO = alertConfigService.getByQuery(
                AlertConfigBO.builder().id(param.getId()).build());
            if(Objects.isNull(alertConfigBO)){
                throw new WarnException("告警配置id未找到");
            }
        } else {
            alertConfigBO = alertConfigService.getByQuery(
                AlertConfigBO.builder().alertId(param.getAlertId()).project(param.getProject()).build());
            if(Objects.isNull(alertConfigBO)){
                alertConfigBO = AlertConfigBO.builder()
                    .alertId(param.getAlertId())
                    .project(param.getProject())
                    .build();
                alertConfigService.insertOne(alertConfigBO);
            }
        }
        if(StringUtils.isNotBlank(param.getAlertName())){
            alertConfigBO.setAlertName(param.getAlertName());
        }
        if(Objects.nonNull(param.getActionTypes())){
            alertConfigBO.setActionTypes(String.join("|", param.getActionTypes()));
        }
        if(Objects.nonNull(param.getMinActionSeverity())){
            alertConfigBO.setMinActionSeverity(param.getMinActionSeverity());
        }
        if(Objects.nonNull(param.getEnableStatus())){
            alertConfigBO.setEnableStatus(param.getEnableStatus());
        }
        alertConfigService.updateOne(alertConfigBO);
    }

    @Override
    @Transactional(transactionManager = "mtTransactionManager")
    public void deleteAlertConfig(Long id) {
        alertConfigService.deleteOne(id);
        alertChatBindService.deleteByAlertConfigId(id);
        alertUserBindService.deleteByAlertConfigId(id);
    }

    @Override
    public void alertChatBind(AlertChatBindParam alertChatBindParam) {
        checkAlertChatBindParam(alertChatBindParam);
        if(Objects.isNull(alertChatBindParam.getId())){
            AlertChatBindBO alertChatBindBO = AlertChatBindBO.builder()
                .alertConfigId(alertChatBindParam.getAlertConfigId())
                .chatGroupId(alertChatBindParam.getChatGroupId())
                .msgType(alertChatBindParam.getMsgType())
                .atType(alertChatBindParam.getAtType())
                .msgTemplate(alertChatBindParam.getMsgTemplate())
                .build();
            if(StringUtils.isBlank(alertChatBindParam.getMsgTemplate())){
                alertChatBindBO.setMsgType(MsgTypeEnum.POST.getCode());
            }
            if(StringUtils.isBlank(alertChatBindParam.getAtType())){
                alertChatBindBO.setAtType(AtTypeEnum.NONE.getCode());
            }
            if(!CollectionUtils.isEmpty(alertChatBindParam.getAtUserInfoIds())){
                alertChatBindBO.setAtUserInfoIds(String.join("|", alertChatBindParam.getAtUserInfoIds()));
            }
            alertChatBindService.insert(alertChatBindBO);
        } else {
            AlertChatBindBO alertChatBindBO = alertChatBindService.getById(alertChatBindParam.getId());
            if(Objects.isNull(alertChatBindBO)){
                throw new WarnException("此绑定id不存在");
            }
            if(Objects.nonNull(alertChatBindParam.getAlertConfigId())){
                alertChatBindBO.setAlertConfigId(alertChatBindParam.getAlertConfigId());
            }
            if(Objects.nonNull(alertChatBindParam.getChatGroupId())){
                alertChatBindBO.setChatGroupId(alertChatBindParam.getChatGroupId());
            }
            if(Objects.nonNull(alertChatBindParam.getMsgType()) ){
                if(StringUtils.isBlank(alertChatBindParam.getMsgType())){
                    alertChatBindBO.setMsgType(MsgTypeEnum.POST.getCode());
                } else {
                    alertChatBindBO.setMsgType(alertChatBindParam.getMsgType());
                }
            }
            if(Objects.nonNull(alertChatBindParam.getAtType())){
                if(StringUtils.isBlank(alertChatBindParam.getAtType())){
                    alertChatBindBO.setAtType(AtTypeEnum.NONE.getCode());
                } else {
                    alertChatBindBO.setAtType(alertChatBindParam.getAtType());
                }
            }
            if(!CollectionUtils.isEmpty(alertChatBindParam.getAtUserInfoIds())){
                alertChatBindBO.setAtUserInfoIds(String.join("|", alertChatBindParam.getAtUserInfoIds()));
            } else if(Objects.nonNull(alertChatBindParam.getAtUserInfoIds())){
                alertChatBindBO.setAtUserInfoIds("");
            }
            alertChatBindService.update(alertChatBindBO);
        }
    }

    @Override
    public void alertUserBind(AlertUserBindParam alertUserBindParam) {
        checkAlertUserBindParam(alertUserBindParam);
        if(Objects.isNull(alertUserBindParam.getId())){
            AlertUserBindBO alertUserBindBO = AlertUserBindBO.builder()
                .alertConfigId(alertUserBindParam.getAlertConfigId())
                .userInfoId(alertUserBindParam.getUserInfoId())
                .msgType(alertUserBindParam.getMsgType())
                .msgTemplate(alertUserBindParam.getMsgTemplate())
                .build();
            if(StringUtils.isBlank(alertUserBindParam.getMsgTemplate())){
                alertUserBindBO.setMsgType(MsgTypeEnum.POST.getCode());
            }
            alertUserBindService.insert(alertUserBindBO);
        } else {
            AlertUserBindBO alertUserBindBO = alertUserBindService.getById(alertUserBindParam.getId());
            if(Objects.isNull(alertUserBindBO)){
                throw new WarnException("此绑定id不存在");
            }
            if(Objects.nonNull(alertUserBindParam.getAlertConfigId())){
                alertUserBindBO.setAlertConfigId(alertUserBindParam.getAlertConfigId());
            }
            if(Objects.nonNull(alertUserBindParam.getUserInfoId())){
                alertUserBindBO.setUserInfoId(alertUserBindParam.getUserInfoId());
            }
            if(Objects.nonNull(alertUserBindParam.getMsgType())){
                if(StringUtils.isBlank(alertUserBindParam.getMsgType())){
                    alertUserBindBO.setMsgType(MsgTypeEnum.POST.getCode());
                } else {
                    alertUserBindBO.setMsgType(alertUserBindParam.getMsgType());
                }
            }
            alertUserBindService.update(alertUserBindBO);
        }
    }

    @Override
    public void deleteAlertChatBind(Long id) {
        AlertChatBindBO alertChatBindBO = alertChatBindService.getById(id);
        if(Objects.isNull(alertChatBindBO)){
            throw new WarnException("告警配置未找到");
        }
        alertChatBindService.deleteById(id);
    }

    @Override
    public void deleteAlertUserBind(Long id) {
        AlertUserBindBO alertUserBindBO = alertUserBindService.getById(id);
        if(Objects.isNull(alertUserBindBO)){
            throw new WarnException("告警配置未找到");
        }
        alertUserBindService.deleteById(id);
    }

    @Override
    public void saveUserConfig(SaveUserConfigParam saveUserConfigParam) {
        if(Objects.isNull(saveUserConfigParam.getId())){
            if(StringUtils.isBlank(saveUserConfigParam.getFeishuOpenId())
                || StringUtils.isBlank(saveUserConfigParam.getFeishuUserId())
                || StringUtils.isBlank(saveUserConfigParam.getFeishuUnionId())
                || StringUtils.isBlank(saveUserConfigParam.getName())
                || StringUtils.isBlank(saveUserConfigParam.getPhone())
                || StringUtils.isBlank(saveUserConfigParam.getMail())){
                FeishuUserInfoDTO feishuUserInfoDTO = feiShuManager.getUserInfo(
                    saveUserConfigParam.getFeishuUserId(),
                    ReceiveIdTypeEnum.USER_ID.getCode(), null, feiShuFacade.getAccessToken());
                if(StringUtils.isBlank(saveUserConfigParam.getFeishuOpenId())){
                    saveUserConfigParam.setFeishuOpenId(Optional.ofNullable(feishuUserInfoDTO).map(FeishuUserInfoDTO::getOpenId).orElse(null));
                }
                if(StringUtils.isBlank(saveUserConfigParam.getFeishuUnionId())){
                    saveUserConfigParam.setFeishuUnionId(Optional.ofNullable(feishuUserInfoDTO).map(FeishuUserInfoDTO::getUnionId).orElse(null));
                }
                if(StringUtils.isBlank(saveUserConfigParam.getName())){
                    saveUserConfigParam.setName(Optional.ofNullable(feishuUserInfoDTO).map(FeishuUserInfoDTO::getName).orElse(null));
                }
                if(StringUtils.isBlank(saveUserConfigParam.getPhone())){
                    saveUserConfigParam.setPhone(Optional.ofNullable(feishuUserInfoDTO).map(FeishuUserInfoDTO::getMobile).map(x -> x.replace("+86", "")).orElse(null));
                }
                if(StringUtils.isBlank(saveUserConfigParam.getMail())){
                    saveUserConfigParam.setMail(Optional.ofNullable(feishuUserInfoDTO).map(FeishuUserInfoDTO::getEmail).orElse(null));
                }
            }
            UserInfoBO infoBO = userInfoService.queryByMail(saveUserConfigParam.getMail());
            if(Objects.nonNull(infoBO)){
                infoBO.setFeishuOpenId(saveUserConfigParam.getFeishuOpenId());
                infoBO.setFeishuUserId(saveUserConfigParam.getFeishuUserId());
                infoBO.setFeishuUnionId(saveUserConfigParam.getFeishuUnionId());
                infoBO.setPhone(saveUserConfigParam.getPhone());
                infoBO.setMail(saveUserConfigParam.getMail());
                infoBO.setWorkWechatOpenId(saveUserConfigParam.getWorkWechatOpenId());
                userInfoService.updateOne(infoBO);
            } else {
                UserInfoBO userInfoBO = UserInfoBO.builder()
                    .name(saveUserConfigParam.getName())
                    .feishuUserId(saveUserConfigParam.getFeishuUserId())
                    .feishuOpenId(saveUserConfigParam.getFeishuOpenId())
                    .feishuUnionId(saveUserConfigParam.getFeishuUnionId())
                    .phone(saveUserConfigParam.getPhone())
                    .mail(saveUserConfigParam.getMail())
                    .workWechatOpenId(saveUserConfigParam.getWorkWechatOpenId())
                    .build();
                userInfoService.insertOne(userInfoBO);
            }
        } else {
            UserInfoBO userInfoBO = UserInfoBO.builder()
                .id(saveUserConfigParam.getId())
                .name(saveUserConfigParam.getName())
                .feishuUserId(saveUserConfigParam.getFeishuUserId())
                .feishuOpenId(saveUserConfigParam.getFeishuOpenId())
                .feishuUnionId(saveUserConfigParam.getFeishuUnionId())
                .phone(saveUserConfigParam.getPhone())
                .mail(saveUserConfigParam.getMail())
                .workWechatOpenId(saveUserConfigParam.getWorkWechatOpenId())
                .build();
            userInfoService.updateOne(userInfoBO);
        }
    }

    private void checkAlertChatBindParam(AlertChatBindParam alertChatBindParam){
        if(StringUtils.isNotBlank(alertChatBindParam.getAtType())){
            AtTypeEnum atTypeEnum = AtTypeEnum.getEnumByCode(alertChatBindParam.getAtType());
            if(Objects.isNull(atTypeEnum)){
                throw new WarnException("atType不存在");
            }
        }

        if(StringUtils.isNotBlank(alertChatBindParam.getMsgType())){
            MsgTypeEnum msgTypeEnum = MsgTypeEnum.getEnumByCode(alertChatBindParam.getMsgType());
            if(Objects.isNull(msgTypeEnum)){
                throw new WarnException("msgType不存在");
            }
        }
        if(!CollectionUtils.isEmpty(alertChatBindParam.getAtUserInfoIds())){
            List<Long> userIds = alertChatBindParam.getAtUserInfoIds().stream().map(Long::valueOf)
                .collect(
                    Collectors.toList());
            Map<Long, UserInfoBO> userInfoBOMap = userInfoService.getByIds(userIds);
            userIds.forEach(userId -> {
                if(!userInfoBOMap.containsKey(userId)){
                   throw new WarnException("用户id" + userId + "未找到");
                }
            });
        }
    }

    private void checkAlertUserBindParam(AlertUserBindParam alertUserBindParam){
        if(StringUtils.isNotBlank(alertUserBindParam.getMsgType())){
            MsgTypeEnum msgTypeEnum = MsgTypeEnum.getEnumByCode(alertUserBindParam.getMsgType());
            if(Objects.isNull(msgTypeEnum)){
                throw new WarnException("msgType不存在");
            }
        }
    }
}
